package DatabaseManaging;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import Autodesk.ParseLogs;
import DatabaseManaging.Models.Product;
import WebserviceChecker.ProductWbChecker;

public class ProductDatabaseChecker extends DatabaseChecker{
	private static Logger logger = Logger.getLogger(ParseLogs.class);

	public ProductDatabaseChecker() {
		super(new JdbcProductsDao());

	}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//							//	DatabaseChecker Methods //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	@Override
	public String findRepeated(ArrayList<String> listnewRegs,
			String documentLine) {
		String result = "0";
		String[] docSplitted = documentLine.split("\t");
		String product = docSplitted[1];
		String[] valueSplitted = null;
		for (int i = 0; i < listnewRegs.size(); i++) {
			valueSplitted = listnewRegs.get(i).split("\t");
			if (product.equals(valueSplitted[1])) {
				result = listnewRegs.get(i);
				return result;
			}

		}
		return result;
	}
	@Override
	public void updateDatabase(String abs, String product_id) {
		String[] absSp = abs.split("\t");
		String query = "UPDATE akn_product_dim SET";
		for (int i = 0; i < absSp.length; i++) {
			query = query + " product_abbr" + Integer.toString(i + 1) + "='"
					+ absSp[i] + "'";
			if (i != absSp.length - 1) {
				query = query + ",";
			}
		}
		query = query + " WHERE product_dim_id =" + product_id + ";";
		DatabaseManager db = new DatabaseManager();
		db.executeQuery(query);
		logger.info("QUERY: " + query);
		logger.info("Succesfully Inserted.");
	}
	@Override
	public String extractAbbs(String abProductDocument, String abProductList) {
		String abs="";
		ArrayList<String> listAbs=new ArrayList<String>();
		String[] abProductDocSpl=abProductDocument.split("\t");
		String[] abProductListSP=abProductList.split("\t");
		for(int i=2;i<7 && !abProductDocSpl[i].equals("");i++){
			listAbs.add(abProductDocSpl[i]);
		}
		
		for(int j=2;j<7 && !abProductListSP[j].equals("");j++){
			if(!listAbs.contains(abProductListSP[j])){
				listAbs.add(abProductListSP[j]);
			}
		}
		for(int i=0;i<listAbs.size();i++){
			abs=abs+listAbs.get(i)+"\t";
		}
		return abs;				
	}
	@Override
	public void checkDatabase(ArrayList<String> parciaList,
			String documentLine,PrintWriter pw, String[] docLineSp,
			String productList) {
		String abs;
		ProductWbChecker productChecker=new ProductWbChecker();
		String [] productListSplit=productList.split("\t");
		if(productListSplit[8].equals(docLineSp[8])){//Compare Releases
			if(!this.CompareAbbs(documentLine, productList)){
				logger.info("FIND REPEATED:"+productList+"-"+documentLine);
				abs=this.extractAbbs(documentLine, productList);
				String line=productChecker.writeProductLine(docLineSp[1], abs, docLineSp[7], docLineSp[8],docLineSp[0]);
				pw.println(line);
				
				logger.info("UPDATED:"+documentLine);
				this.updateDatabase(abs, docLineSp[0]);
			}else{
				pw.println(documentLine);
			}
			parciaList.remove(productList);
			logger.info("REMOVED FROM LIST BECAUSE THEY ARE STORED IN THE DATABASE:"+productList);
			logger.info("-------------------------------------------");
		}else{
			if(!this.CompareAbbs(documentLine, productList)){
					logger.info("FIND REPEATED:"+productList+"-"+documentLine);
					abs=this.extractAbbs(documentLine, productList);
					
					String docline=productChecker.writeProductLine(docLineSp[1], abs, docLineSp[7], docLineSp[8],docLineSp[0]);
					pw.println(docline);
					logger.info("WRITTEN in the doc: "+docline);

					String productAddedAbb=productChecker.writeProductLine(productListSplit[1], abs, productListSplit[7], productListSplit[8],productListSplit[0]);
					if(!parciaList.remove(productList)){
						System.out.print("CAN NOT REMOVE THE ELEMNT");
						logger.info(productList);
					}
					parciaList.add(productAddedAbb);
					logger.info("ADDED TO LIST:"+productAddedAbb);
					
					this.updateDatabase(abs, docLineSp[0]);
					logger.info("UPDATED:"+documentLine);
					logger.info("-------------------------------------------");
				}else{
					pw.println(documentLine);
				}
		}
	}
	
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	
	@Override
	public Object getElement(String prodList) {
		Product product= ProductBuilder.build(prodList);
		return product;
	}

	
	@Override
	public ArrayList<Object> findEqualsName(Object product) {
		Product prod=(Product) product;
		return this.getJdbc().findElementby(prod.getName());
	}
	
	
	@Override
	public Object updateRegister(ArrayList<Object> listDBWithEqName,
			Object productFromList) {
		Product prdList=(Product) productFromList;
		for(int i=0;i<listDBWithEqName.size();i++){
			Product prdDB=(Product)listDBWithEqName.get(i);
			prdList=addAbbsToProduct(prdList, prdDB);
		}
		return prdList;
	}
	public Product addAbbsToProduct(Product productToAdd, Product prdTocheck) {
		for(int j=0;j<prdTocheck.getAbbs().size();j++){//ITER BETWEEN ABBS
			if(!productToAdd.getAbbs().contains(prdTocheck.getAbbs().get(j))){
				if(containsYear(prdTocheck.getAbbs().get(j))){  //an abb could be "Autocad 2010" for example
					if(getYear(prdTocheck.getAbbs().get(j)).equals(productToAdd.getRelease_year())){
						productToAdd.getAbbs().add(prdTocheck.getAbbs().get(j));
					}
				}else{
					productToAdd.getAbbs().add(prdTocheck.getAbbs().get(j));
				}
			}
		}
		return productToAdd;
	}
	
	@Override
	public void updateDatabase(ArrayList<Object> listDBWithEqName,
			Object productFromList) {
		Product prdList=(Product) productFromList;
		for(int i=0;i<listDBWithEqName.size();i++){
			Product prdDB=(Product)listDBWithEqName.get(i);
			Product prdDB2=new Product(prdDB);
			prdDB2=addAbbsToProduct(prdDB2, prdList);
			if(!(prdDB2.getAbbs().equals(prdDB.getAbbs()))){
				this.getJdbc().updateAbbsByName(Long.toString(prdDB.getId()), prdDB2.getAbbs());
				logger.info("Updated register of:"+prdDB2);
			}
		}
	}
	
	private static boolean containsYear(String value){
		boolean year;
		Pattern yearPattern = Pattern
				.compile("20[0-9][0-9]");
		Matcher yearMatcher = yearPattern.matcher(value);
		year = yearMatcher.find() ? true : false;
		return year;
	}
	
	private static String getYear(String value){
		String year="";
		Pattern yearPattern = Pattern
				.compile("20[0-9][0-9]");
		Matcher yearMatcher = yearPattern.matcher(value);
		year = yearMatcher.find() ? yearMatcher.group() : value;
		return year;
	}
	
	
	@Override
	public void InsertIfitIsNOTRepeated(ArrayList<Object> listDBWithEqName,
			Object productFromList) {
		Product prdList=(Product) productFromList;
		if(!isRepeatedInDB(listDBWithEqName,productFromList)){
			this.getJdbc().insertElement(prdList);
			logger.info("Inserted:"+prdList);
		}		
	}
	
	public boolean isRepeatedInDB(ArrayList<Object> listDBWithEqName,Object productFromList) {
		boolean isRepeated=false;
		Product prdList=(Product) productFromList;
		for(int i=0;i<listDBWithEqName.size();i++){
			Product prdDB=(Product)listDBWithEqName.get(i);
			if(prdList.getName().equals(prdDB.getName()) 
					&& prdList.getRelease().equals(prdDB.getRelease())){
				isRepeated=true;
			}
		}
		return isRepeated;
	}


	
}
